package net.lzzy.controller;


import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.UUID;

@Controller
public class FileController {

    //定义文件上传路径
    private static final String dirPath = "E:/File/";

    @GetMapping("/upload")
    public String upLoad(){
        return "upload";
    }
    
    @PostMapping("/upload")
    public String upLoadFile(@RequestPart("files") MultipartFile[] files, Model model){
        //MultipartFile是SpringMVC提供简化上传操作的工具类。
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                String fileName = file.getOriginalFilename();
                //通用唯一识别码，UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来，每个人都可以创建不与其它人冲突的 UUID，就不需考虑数据库创建时的名称重复问题
                //fileName = UUID.randomUUID()+"_"+fileName;
                File filePath = new File(dirPath);
                if (!filePath.exists()) {
                    if (!filePath.mkdirs()) {
                        model.addAttribute("msg","创建目录失败！！");
                        return "upload";
                    }
                }
                File newFile = new File(dirPath+fileName);
                //判断是否有同名文件存在
                if (newFile.exists()){
                    model.addAttribute("msg","已有同名文件存在！！");
                    return "upload";
                }
                //上传文件
                try {
                    file.transferTo(newFile);
                } catch (Exception e) {
                    model.addAttribute("msg", "上传失败:"+e.getMessage());
                }
                model.addAttribute("msg","上传成功");
            }
            else
            {
                model.addAttribute("msg", "请选择上传文件！");
            }
        }
        return "upload";
    }


    @GetMapping("/download")
    public String download(Model model){
        File dir = new File(dirPath);
        if (dir.exists() && dir.list().length>0) {
            String[] files = dir.list();
            model.addAttribute("files", files);
        }
        else {
            model.addAttribute("msg", "无下载文件");
        }
        return "download";
    }

    @GetMapping("/downloadfile")
    //@GetMapping("/downloadfile/{filename}")
    //ResponseEntity继承了HttpEntity类，HttpEntity代表一个http请求或者响应实体，其内部有两个成员变量：header及body，代表http请求或响应的header及body，其中的body是泛化的。
    //一个ResponseEntity基本可以代表完整的http的请求或响应了。这其实就是ResponseEntity类的作用。使用ResponseEntity作为controller的返回值，我们可以方便地处理响应的header，状态码以及body.
    public ResponseEntity<byte[]> downloadFile(@RequestParam("filename") String fileName) throws UnsupportedEncodingException {
        //根据文件所在路径读取文件全路径
        File file = new File(dirPath + File.separator + fileName);
        HttpHeaders httpHeaders = new HttpHeaders();
        //以下载方式打开，不设置默认直接浏览器打开
        httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, "UTF-8"));
        //以二进制流的形式下载文件数据
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        try {
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), httpHeaders, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED);
        }
    }
}
